package xyz.labmem.base.core.tool

import cn.hutool.core.util.ObjectUtil
import cn.hutool.core.util.StrUtil
import cn.hutool.extra.servlet.ServletUtil
import cn.hutool.http.useragent.Browser
import cn.hutool.http.useragent.UserAgent
import cn.hutool.http.useragent.UserAgentUtil
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import xyz.labmem.base.core.consts.UNKNOWN
import xyz.labmem.base.core.error.AppException
import java.io.IOException
import java.net.InetAddress
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession

/**
 * httpServlet工具
 * @Author lty
 * @Date 2021/12/16 13:44
 */
/**
 * 获取客户端浏览器
 */
fun HttpServletRequest.getBrowser(): String {
    val userAgent = this.getUserAgent()
    return if (ObjectUtil.isEmpty(userAgent)) {
        "-"
    } else {
        val browser = userAgent.browser.toString()
        if (UNKNOWN == browser) "-" else browser
    }
}

/**
 * 获取客户端操作系统
 */
fun HttpServletRequest.getOS(): String {
    val userAgent = this.getUserAgent()
    return if (ObjectUtil.isEmpty(userAgent)) {
        "-"
    } else {
        val os = userAgent.os.toString()
        if (UNKNOWN == os) "-" else os
    }
}

/**
 * 获取请求代理头
 */
private fun HttpServletRequest.getUserAgent(): UserAgent {
    val userAgentStr = ServletUtil.getHeaderIgnoreCase(this, "User-Agent")
    val userAgent = UserAgentUtil.parse(userAgentStr)
    //判空
    if (ObjectUtil.isNotEmpty(userAgentStr)) {
        //如果根本没获取到浏览器
        if (UNKNOWN == userAgent.browser.name) {
            //则将ua设置为浏览器
            userAgent.browser = Browser(userAgentStr, null, "")
        }
    }
    return userAgent
}

/**
 * 获取客户端ip
 */
fun HttpServletRequest.getIp(): String {

    var ipAddress = this.getHeader("Proxy-Client-ipCode")
    try {
        if (ipAddress != null && ipAddress.isNotEmpty() && !"unknown".equals(ipAddress, ignoreCase = true)) {
            return ipAddress
        }
        ipAddress = this.getHeader("x-forwarded-for")
        if (ipAddress != null && ipAddress.isNotEmpty() && !"unknown".equals(ipAddress, ignoreCase = true)) {
            val index = ipAddress.indexOf(",")
            if (index > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","))
            }
            return ipAddress
        }
        ipAddress = this.remoteAddr
        if ("127.0.0.1" == ipAddress || "0:0:0:0:0:0:0:1" == ipAddress) {
            ipAddress = InetAddress.getLocalHost().hostAddress
        }
    } catch (e: Exception) {
        throw AppException("获取ip地址错误", e)
    }
    return ipAddress

}

/**
 * Describe: 获取 HttpServletRequest 对象
 * Param null
 * Return HttpServletRequest
 */
fun getRequest(): HttpServletRequest {
    val servletRequestAttributes = RequestContextHolder.getRequestAttributes() as ServletRequestAttributes
    return servletRequestAttributes.request
}

/**
 * Describe: 获取 HttpServletResponse 对象
 * Param null
 * Return HttpServletResponse
 */
fun getResponse(): HttpServletResponse? {
    val servletRequestAttributes = RequestContextHolder.getRequestAttributes() as ServletRequestAttributes
    return servletRequestAttributes.response
}

/**
 * Describe: 获取 HttpServletSession 对象
 * Param null
 * Return HttpServletSession
 */
fun getSession(): HttpSession {
    val servletRequestAttributes = RequestContextHolder.getRequestAttributes() as ServletRequestAttributes
    return servletRequestAttributes.request.session
}

/**
 * Describe: 判断是否为 Ajax 请求
 * Param null
 * Return HttpServletSession
 */
fun HttpServletRequest.isAjax(): Boolean {
    val requestType = this.getHeader("X-Requested-With")
    val authHeader = this.getHeader("RequestType")
    return "XMLHttpRequest" == requestType || StrUtil.isNotBlank(authHeader)
}

/**
 * Describe: Response 对象写出数据
 * Param: msg 消息数据
 * Return null
 */
@Throws(IOException::class)
fun HttpServletResponse.write(msg: String) {
    this.setHeader("Content-type", "application/json;charset=UTF-8")
    this.characterEncoding = "UTF-8"
    this.writer.write(msg)
}

/**
 * Describe: Response 对象写出数据
 * Param: msg 消息数据
 * Return null
 */
@Throws(IOException::class)
fun write(msg: String) = getResponse()?.write(msg)

/**
 * 获取查询参数
 */
fun getQueryParam(): String? = getRequest().queryString

/**
 * 获取请求地址
 */
fun getRequestURI(): String? = getRequest().requestURI

/**
 * 获取客户端地址
 */
fun getRemoteHost(): String? {
    var remoteHost = getRequest().remoteHost
    if (remoteHost == "0:0:0:0:0:0:0:1") {
        remoteHost = "127.0.0.1"
    }
    return remoteHost
}

/**
 * 获取当前请求方法
 */
fun getMethod(): String? = getRequest().method
